﻿using System;
using System.Reflection;
using Fortune.Attributes.stereotype;
using Fortune.Context;
using Fortune.Log;
using Fortune.Util;
using FreeSql;
using UnityEngine;

namespace Fortune.Loader
{
    /// <summary>
    /// 数据库加载器
    /// </summary>
    // ReSharper disable once InconsistentNaming
    public static class FreeSQLoader
    {
        private static readonly FortuneLogger logger = FortuneLogger.newInstance(typeof(IFreeSql));

        public static void load()
        {
            try
            {
                IFreeSql iFreeSql = new FreeSqlBuilder()
                    .UseConnectionString(DataType.Sqlite, FortuneContext.connectionUrl)
                    .Build();
                iFreeSql.Aop.CurdAfter += (sender, args) =>
                {
                    logger.info($"执行语句：\n{compressSql(args.Sql)}");
                };
                FortuneContext.freeSql = iFreeSql;
                logger.info("freeSQL加载成功");
                int repositoryCount = loadRepository();
                logger.info($"DAO层加载成功，加载数量：{repositoryCount}");
            }
            catch (Exception e)
            {
                logger.error("FreeSQL初始化异常", e);
                throw;
            }
        }

        private static string compressSql(string sql)
        {
            if (sql == null || sql.Length <= 512)
            {
                return sql;
            }

            return sql.Substring(0, 512) + "...";
        }

        /// <summary>
        /// 加载仓库类
        /// </summary>
        private static int loadRepository()
        {
            int repositoryCount = 0;
            Type[] repositories = typeof(RepositoryAttribute).Assembly.GetExportedTypes();
            foreach (Type repository in repositories)
            {
                RepositoryAttribute repositoryAttribute = repository.GetCustomAttribute<RepositoryAttribute>();
                if (repositoryAttribute == null)
                {
                    // 没有RepositoryAttribute则跳过
                    continue;
                }

                if (!TypeUtil.hasImplementedRawGeneric(repository, typeof(BaseRepository<>)))
                {
                    // 未继承BaseRepository<>则跳过
                    continue;
                }
                
                logger.info($"注册bean: {repository.FullName}");
                FortuneContext.registerBean(Activator.CreateInstance(repository));
                repositoryCount++;
            }

            return repositoryCount;
        }
    }
}